package com.itheima.esdemo;

import com.alibaba.fastjson.JSON;
import com.itheima.esdemo.pojo.User;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.autoconfigure.security.SecurityProperties;

import javax.swing.text.Highlighter;
import java.io.IOException;
import java.util.List;
import java.util.Map;

//聚合查询
public class EsDemo05 {
    private RestHighLevelClient restHighLevelClient;
    //配置客户端连接地址
    @Before
    public void init(){
        restHighLevelClient = new RestHighLevelClient(
                RestClient.builder(
                        // 要连接的es地址
                        new HttpHost("192.168.200.150",9200,"http")
                        ,new HttpHost("192.168.200.151",9200,"http")   // 如果是集群的话可以写多个
                        ,new HttpHost("192.168.200.152",9200,"http")
                        ,new HttpHost("192.168.200.153",9200,"http")
                )
        );
    }

    /**
     * 查询所有数据
     * 1. 先按照性别进行分桶
     * 2. 求出每个分桶下年龄的平均值
     */
    @Test
    public void aggergations() throws IOException {
        //1.创建请求对象
        SearchRequest request = new SearchRequest();
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //构建分桶的聚合条件
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("terms_by_gender").field("gender");
        //构建一个桶内求平均值的聚合条件
        AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("avg_by_age").field("age");
        termsAggregationBuilder.subAggregation(avgAggregationBuilder);
        builder.aggregation(termsAggregationBuilder);
        request.source(builder);
        //2.调用客户端处理请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //3.解析结果
        Terms termsByGender = response.getAggregations().get("terms_by_gender");
        // 得到分桶信息
        List<? extends Terms.Bucket> buckets = termsByGender.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println("当前分桶的key: " + bucket.getKeyAsString());
            System.out.println("当前分桶的数量: " + bucket.getDocCount());
            // 获取子聚合的总结果
            Aggregations subAggs = bucket.getAggregations();
            Avg avgResult = subAggs.get("avg_by_age");//获取分桶下的平均值
            System.out.println("当前分桶的年龄平均值: " + avgResult.getValue());
        }

    }

    //note: match   查询 唱歌javaee  note能够高亮显示  显示红色
    @Test
    public void highlight() throws IOException {
        //1.创建请求对象
        SearchRequest request = new SearchRequest();
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("note", "唱歌javaee"));
        // 构建高亮条件
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("note");// 设置高亮字段
        highlightBuilder.preTags("<span style='color:red'>");//前置标签
        highlightBuilder.postTags("</span>");//后置标签
        builder.highlighter(highlightBuilder);
        request.source(builder);
        //2.调用客户端处理请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //3.解析结果
        SearchHits hits = response.getHits();
        System.out.println("查询结果数量: " +hits.getTotalHits().value);
        SearchHit[] docList = hits.getHits();
        //遍历文档
        for (SearchHit searchHit : docList) {
            String userJson = searchHit.getSourceAsString();
            User user = JSON.parseObject(userJson, User.class);//将结果的json反序列化得到user对象
            // 获取高亮的结果 ，设置到user.setNote(高亮结果);
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            // 得到note字段所对应的高亮结果
            HighlightField highlightField = highlightFields.get("note");
            // 获取高亮的片段数组
            Text[] fragments = highlightField.getFragments();
            // 将所有高亮的片段拼接到一个字符串上，得到完成高亮结果
            // String str = StringUtils.join(fragments);
            StringBuilder sb = new StringBuilder();
            for (Text fragment : fragments) {
                sb.append(fragment);
            }
            // 将高亮的处理结果设置到user的note字段中
            user.setNote(sb.toString());
            System.out.println(user);
        }

    }





    //关闭客户端
    @After
    public void close() throws IOException {
        restHighLevelClient.close();
    }
}
